Skip to content

AzLocal.UpdateManagement v0.8.74 - consistent 'Up to Date' classification, No-Clusters-Ready breakdown, deep-tree Progress column, step-summary hyperlink tidy-up#80

Merged
NeilBird merged 9 commits into
mainfrom
users/nebird/development
Jun 12, 2026
Merged

AzLocal.UpdateManagement v0.8.74 - consistent 'Up to Date' classification, No-Clusters-Ready breakdown, deep-tree Progress column, step-summary hyperlink tidy-up#80
NeilBird merged 9 commits into
mainfrom
users/nebird/development

Conversation

@NeilBird

@NeilBird NeilBird commented Jun 12, 2026

Copy link
Copy Markdown
Owner

Summary

v0.8.74 makes the "Up to Date" cluster classification consistent across the Step.5 readiness report, the Step.7 readiness gate, and the Step.9 fleet update-status report; corrects the long-standing Progress column under-reporting in the Step.7 in-flight monitor and the standalone HTML "Recent Update Run History" report; and drops the dead target="_blank" portal-link attributes that the GitHub Actions / Azure DevOps step-summary sanitisers were stripping anyway (replaced with an explicit Ctrl/Cmd/middle-click tip above each affected table).

No public API or export-count change (still 60 exports).

What changed

Consistent "Up to Date" classification

  • Fixed: fully-patched clusters were mis-classified as "not ready". Step.5 (Export-AzLocalClusterUpdateReadinessReport) showed 0 in its "Up to date" count and listed such clusters in the "Not-Ready clusters (review first)" table; Step.7 (Export-AzLocalClusterReadinessGateReport) rendered them with a no-entry icon in the binary Ready? column - both implying failure. Root cause: the "Up to Date" test required AllAvailableUpdates to be empty, but a cluster that has installed all updates still lists those (now-Installed) package names there.
  • Added Get-AzLocalClusterReadinessStatus private helper - the single source of truth for the readiness priority cascade (UpdateFailed > ActionRequired > HealthFailure > SbeBlocked > InProgress > ReadyForUpdate > UpToDate > NeedsInvestigation). Step.5, Step.7 and Step.9 all classify through this one helper now.
  • Changed: Step.7's per-cluster table replaces the binary Ready? column with a readable Status column and emits a new additive UP_TO_DATE_COUNT / UpToDateCount step output (-PassThru returns UpToDateCount). Step.5's "All clusters detail" table gets the same readable Status label and excludes Up-to-Date / Ready clusters from its "Not-Ready" table.

No-Clusters-Ready breakdown

  • Add-AzLocalNoReadyClustersStepSummary now accepts -UpToDateCount / -NotReadyCount and renders an Up to Date vs Not Ready breakdown table, so already-patched clusters read as a healthy steady state rather than a fault. When every discovered cluster is up to date it logs an informational notice (not a warning) and points operators to the per-cluster Status / Blocking Reasons detail (the Check Update Readiness table + readiness-report.csv).
  • Both the GitHub Actions and Azure DevOps apply-updates templates wire the two new counts through from the readiness gate job.

Deep-tree Progress column

  • Fixed: the Progress column in the Step.7 in-flight monitor (Export-AzLocalUpdateRunMonitorReport, via Format-AzLocalUpdateRun) and the standalone HTML "Recent Update Run History" table (New-AzLocalFleetStatusHtmlReport, fed by Get-AzLocalFleetStatusData) had always been reporting the coarse top-level wrapper count (typically 1/2 steps) for the whole multi-hour run. Real Azure Local update runs only expose two top-level wrapper steps in properties.progress.steps - Prepare update (Success) and Start update (stays InProgress for the entire run) - so counting that level alone produced 1/2 steps (or 0/2 steps) regardless of real progress.
  • Both reporting paths now walk the full nested step tree via a new private helper, Get-AzLocalUpdateRunStepStats, and report leaf-step completion as M/N steps (P%) (optionally suffixed with , K failed when leaf-level errors are present). Skipped leaves count as completed so a fully-finished run reaches 100%; wrapper steps are excluded so children aren't double-counted.
  • Mirrors how CurrentStep already traverses the tree via Get-DeepestActiveStep.

Step-summary portal hyperlinks: stop pretending target="_blank" works

  • The Cluster / Update portal hyperlinks rendered in Step.7 (Export-AzLocalUpdateRunMonitorReport in-flight + failed-runs tables), Step.8 (Export-AzLocalFleetUpdateStatusReport Update Run History table), and Step.10 (Export-AzLocalFleetHealthStatusReport Fleet Health Overview / By-Reason / Detailed Results tables) always opened in the current tab even though the markdown source emitted target="_blank" rel="noopener" on every anchor.
  • Confirmed in the rendered HTML of a real GitHub Actions job summary: GitHub's GFM sanitiser strips the target attribute entirely and forces rel="nofollow". The Azure DevOps step-summary renderer applies an equivalent sanitisation. The behaviour is platform-imposed and not configurable - see Stack Overflow: open link in new tab with github markdown using target="_blank" (425-upvote accepted answer documents the same conclusion).
  • All three emitters now render plain <a href="...">name</a> with no target / rel attributes (so the markdown source matches what actually reaches the rendered DOM, and the payload is slightly smaller), and each affected table is preceded by an explicit tip:

    Tip: Hold `Ctrl` (or `Cmd` on macOS) when clicking - or middle-click - Cluster or Update links to open them in a new tab. (GitHub markdown strips target="_blank".)

  • The standalone HTML report (New-AzLocalFleetStatusHtmlReport) is unaffected - it is written as a raw .html artifact (not a step-summary), so its existing target="_blank" already works as intended in any browser. No change there.

Housekeeping

  • GENERATED_AGAINST_MODULE_VERSION bumped 0.8.73 -> 0.8.74 across all bundled pipeline templates.
  • CHANGELOG, README ("What's New in v0.8.74"), release-history, module manifest ReleaseNotes (kept under the 10,000-char PSGallery limit), and pipeline appendix doc updated.

Testing

Full Pester suite passes: 1133 passed, 0 failed, 1 skipped (pre-existing skip).

New / updated coverage:

  • Get-AzLocalUpdateRunStepStats regression suite covers nested-tree traversal, Skipped-as-completed accounting, wrapper-step exclusion, the empty/$null cases, and the MaxDepth guard.
  • Get-AzLocalFleetStatusData (HTML / CSV path) asserts the LatestRuns[].Progress field now reports leaf-step M/N steps (P%) for a 5-leaf in-flight fixture rather than the old 1/2 steps.
  • Step.7 / Step.9 step-summary tests now assert plain <a href="...">name</a> markup (no target/rel), regress on target="_blank" ever reappearing, and require the Ctrl-click tip block above the cluster/update tables.

NeilBird added 8 commits June 11, 2026 16:59
…e-triggers marker (GH+ADO)

The schedule-triggers AZLOCAL-CUSTOMIZE marker wrapped ~30 lines of author guidance (incl. the New-AzLocalApplyUpdatesScheduleConfig -OutputPath example and the default-path note). Update-AzLocalPipelineExample preserves the marker BODY from the customer's file, so author corrections inside the marker (e.g. the v0.8.71 .github -> config path fix) never reach an already-deployed consumer. Moved all guidance above the BEGIN marker; marker body now holds only the trigger directive (GH placeholder comment / ADO 'trigger: none'). Queued for next version bump.
…Step.0 -> Step.00 ... Step.9 -> Step.09)

Queued for 0.8.72 (no version bump). The GitHub Actions sidebar and ADO
pipelines list sort workflows alphabetically by their display name, so
Step.10 lexically sorted between Step.1 and Step.2. Zero-padding the
single-digit step numbers makes Step.10 sort last as intended.

Scope (display/title text only, fully reversible):
- GitHub Actions workflow `name:` fields (10 files; Step.10 unchanged)
- Azure DevOps `name:` / stage `displayName:` Step.N labels
- Header-comment titles (`# Step.N - ...`) on both platforms
- One ADO "HOW TO RUN" prose line tracking its renamed display name

Left unchanged: artifact names (azlocal-step.N-* functional identifiers)
and cross-reference prose (e.g. "Step.9 / Step.10 wiring").
Patch release. No module code, API, or export-count change (60 exports).
Bundles the two pipeline-template improvements committed on this branch
since v0.8.71:

Fixed
- apply-updates.yml (GH + ADO): moved the schedule-path author guidance
  (incl. the New-AzLocalApplyUpdatesScheduleConfig -OutputPath example and
  the default-path note) OUTSIDE the schedule-triggers AZLOCAL-CUSTOMIZE
  marker. Update-AzLocalPipelineExample preserves the marker body from the
  customer's file, so guidance corrections inside the marker never reached
  already-deployed consumers. Guidance now lives above the BEGIN marker.

Changed
- Zero-padded single-digit Step.N pipeline display names to two digits
  (Step.0 -> Step.00 ... Step.9 -> Step.09) so Step.10 sorts last in the
  GitHub Actions sidebar / Azure DevOps pipelines list. Display/title text
  only; artifact names and cross-reference prose unchanged.
- Bumped GENERATED_AGAINST_MODULE_VERSION pins 0.8.71 -> 0.8.72 across all
  bundled pipeline YAMLs.

Version bump applied to psd1/psm1/CHANGELOG/README/Tests/docs.
…s inline into Eligible rings column

- Get-AzLocalApplyUpdatesScheduleCycleCalendar: when -ClusterRingCounts is supplied, relabel the
  "Eligible rings" header to "Eligible rings (cluster count)" and append each ring's count inline
  (e.g. `Prod` (9), `Canary` (3)); removed the separate "Clusters in ring(s)" column. Per-ring
  projection table (-IncludePerRingSummary) keeps its standalone "Cluster count" column.
- Export-AzLocalApplyUpdatesScheduleAudit: build a ring -> tagged-cluster-count map from the cluster
  CSV and forward it to the cycle-calendar cmdlet (the Step.3 render path never passed it before, so
  inline counts were silently absent from production output).
- Tests: updated header/cell assertions for the inline format; added a TOC regression guard that the
  README lists exactly one top-level "What's New" entry (current release only).
- README TOC: removed stale "What's New in v0.8.7" / "v0.8.4" entries; prior versions live under
  Release History.
- Version bump 0.8.72 -> 0.8.73 across psd1/psm1/CHANGELOG/README/tests/docs and all bundled pipeline
  YAML GENERATED_AGAINST_MODULE_VERSION pins.
…akdown

Step.5/Step.7/Step.9 now classify a fully-patched cluster as "Up to Date" via the shared Get-AzLocalClusterReadinessStatus helper instead of implying failure. Step.7's "No Clusters Ready" summary (Add-AzLocalNoReadyClustersStepSummary) now accepts -UpToDateCount/-NotReadyCount and renders an Up-to-Date vs Not-Ready breakdown table, logs a notice (not a warning) when every cluster is already up to date, and points to the per-cluster Status/Blocking Reasons detail. Both apply-updates templates (GitHub Actions + Azure DevOps) wire the two counts through from the readiness gate.

Docs/manifest/changelog/release-history updated; all bundled pipeline templates bump GENERATED_AGAINST_MODULE_VERSION to 0.8.74. Full Pester suite: 1124 passed, 0 failed, 1 skipped.
@NeilBird NeilBird changed the title AzLocal.UpdateManagement v0.8.74 - consistent "Up to Date" classification + No-Clusters-Ready breakdown AzLocal.UpdateManagement v0.8.74 - consistent 'Up to Date' classification, No-Clusters-Ready breakdown, deep-tree Progress column, step-summary hyperlink tidy-up Jun 12, 2026
…s Step.7/8/10 emitters

Fixes the Progress column in the Step.7 in-flight monitor and the standalone
HTML "Recent Update Run History" report - both had been reporting the coarse
top-level wrapper count (typically 1/2 steps) for the entire multi-hour run
because Azure Local only exposes two top-level wrapper steps
(Prepare update + Start update) and Start update stays InProgress end-to-end.
Both paths now traverse the full nested step tree via a new private helper
(Get-AzLocalUpdateRunStepStats) and report leaf-step completion as
M/N steps (P%), optionally suffixed with ", K failed", matching how
CurrentStep already walks the tree via Get-DeepestActiveStep.

Also drops the dead target="_blank" / rel="noopener" portal-link attributes
from every step-summary anchor in Step.7 (Export-AzLocalUpdateRunMonitorReport),
Step.8 (Export-AzLocalFleetUpdateStatusReport) and Step.10
(Export-AzLocalFleetHealthStatusReport). The GitHub GFM step-summary sanitiser
(and the ADO equivalent) strips target entirely and forces rel="nofollow", so
the markdown source has been dead weight. All three emitters now render plain
<a href="...">name</a> and surface an operator tip above each affected table:
"Hold Ctrl (or Cmd on macOS) when clicking - or middle-click - Cluster or
Update links to open them in a new tab. (GitHub markdown strips
target=\"_blank\".)". The standalone HTML report
(New-AzLocalFleetStatusHtmlReport) is unaffected - it ships as a raw .html
artifact, not a step-summary, so its target="_blank" already works.

CHANGELOG, README, release-history, and module manifest ReleaseNotes (kept
under the 10,000-char PSGallery limit; older v0.8.7 entry trimmed to a single
line to make room) updated to describe both fixes. No public API or
export-count change (still 60). Full Pester suite green: 1133 passed,
0 failed, 1 skipped (pre-existing).
@NeilBird
NeilBird merged commit 7ce9048 into main Jun 12, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant